#include <glib.h>
#include <stdlib.h>
#include <stdio.h>
#include <glib-object.h>
#include <dbus/dbus.h>
#include <dbus/dbus-glib.h>

#define OFONO_SERVICE_NAME "org.ofono"
#define OFONO_MANAGER "org.ofono.Manager"
#define OBJECT_PATH "/"
#define OFONO_MESSAGE_MANAGER "org.ofono.MessageManager"
#define OFONO_MODEM_PATH "/phonesim"

static GType getModemsType() {
    // "a(oa{sv})";
    GType map = dbus_g_type_get_map("GHashTable", G_TYPE_STRING, G_TYPE_VARIANT);
    //GType structure = dbus_g_type_get_struct("GStruct", G_TYPE_OBJECT, map);
    //GType array = dbus_g_type_get_structv("GPtrArray", structure);
    return map;
}

static DBusGProxy *getMessageManagerProxy() {
    DBusGConnection *conn = NULL;
    DBusGProxy *messageManager = NULL;
    GError *error = NULL;
    conn = dbus_g_bus_get(DBUS_BUS_SYSTEM, &error);
    if (conn == NULL) {
        fprintf(stderr, "cannot get system dbus");
        return NULL;
    }
    /* retrieve modem list to select which modem to use */
    DBusGProxy *manager = dbus_g_proxy_new_for_name(conn, OFONO_SERVICE_NAME, OBJECT_PATH, OFONO_MANAGER);
    if (manager == NULL) {
        g_print("error getting ofono.Manager");
    }
    /*void *modems;
    if (!dbus_g_proxy_call(manager, "GetModems", &error, G_TYPE_INVALID, DBUS_TYPE_G_OBJECT_ARRAY, modems, G_TYPE_INVALID)) {
        if (error->domain == DBUS_GERROR && error->code == DBUS_GERROR_REMOTE_EXCEPTION) {
            fprintf(stderr, "getMessageManager: caught remote method exception %s:%s", dbus_g_error_get_name(error),
                    error->message);
        } else {
            fprintf(stderr, "error %s\n", error->message);
        }
        return NULL;
    }*/
    messageManager = dbus_g_proxy_new_for_name(conn, OFONO_SERVICE_NAME, OFONO_MODEM_PATH, OFONO_MESSAGE_MANAGER);
    return messageManager;
}

int main(int argc, char **argv) {
    g_type_init();

    DBusGProxy *messageManager = getMessageManagerProxy();
    g_print("messagemanager is 0x%x\n", (unsigned int) messageManager);
    GError *error = NULL;
    const char *dst = "100985";
    const char *msg = "The quick brown fox jumps over the lazy dog.";
    GVariant *path;
    if (!dbus_g_proxy_call(messageManager, "SendMessage", &error, G_TYPE_STRING, dst, G_TYPE_STRING, msg, G_TYPE_INVALID, 
                G_TYPE_VARIANT, &path, G_TYPE_INVALID)) {
        if (error->domain == DBUS_GERROR && error->code == DBUS_GERROR_REMOTE_EXCEPTION) {
            fprintf(stderr, "SendMessage: caught remote method exception %s:%s", dbus_g_error_get_name(error),
                    error->message);
        } else {
            fprintf(stderr, "SendMessage: error %s\n", error->message);
        }
    } else {
        g_print("SendMessage returned '%s'\n", path);
    }
    g_free(path);
    g_object_unref(messageManager);
    return 0;
}
